#include "Follower.h"
#include "Transformation.h"
#include "GameObject.h"

using namespace game_engine;
using namespace game_engine::components;
using namespace game_engine::library;
using namespace game_engine::utils;

///////////////////////////////////////////////////////////////////////////////
// Constructors and Destructors
///////////////////////////////////////////////////////////////////////////////

Follower::Follower(void)
    : Behaviour(), subject(NULL), initialPosition(), subjectPosition(), 
    camFollow(NULL)
{
    type = "Follower";
    slotSubjectHasMoved.AssignFunction(this, &Follower::setSubjectPosition);
}

Follower::Follower(GameObject *obj)
    : Behaviour(obj), subject(NULL), initialPosition(), subjectPosition(), 
    camFollow(NULL)
{
    type = "Follower";
    slotSubjectHasMoved.AssignFunction(this, &Follower::setSubjectPosition);
}

Follower::~Follower(void)
{
    delete camFollow;
}

///////////////////////////////////////////////////////////////////////////////
// Other public methods
///////////////////////////////////////////////////////////////////////////////

void Follower::initialize(void) throw(...)
{
    // Create states for this behaviour
    camFollow = new CameraFollow(this);
    setCurrentState(camFollow);

    // Base class initialization
    Behaviour::initialize();
}

///////////////////////////////////////////////////////////////////////////////
// Slots
///////////////////////////////////////////////////////////////////////////////

INT32 Follower::setSubjectPosition(Point position)
{
    subjectPosition = position;
    return 0;
}

///////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////

GameObject* Follower::getSubject(void) const
{
    return subject;
}

const Point& Follower::getInitialPosition(void) const
{
    return initialPosition;
}

const Point& Follower::getSubjectPosition(void) const
{
    return subjectPosition;
}

///////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////

void Follower::setSubject(GameObject *sbj) throw(...)
{
    Transformation *transf = dynamic_cast<Transformation*> 
        (sbj->getComponent("Transformation"));
    slotSubjectHasMoved.Connect(transf->signalNewPosition);
    subject = sbj;
}

void Follower::setInitialPosition(const utils::Point &pos)
{
    initialPosition = pos;
}
